package com.gpj.learn.concurrent.jol.demo;

import com.gpj.learn.concurrent.jol.Example;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CountDownLatch;

/**
 * @className JolDemo6
 * @description
 *   偏向锁、轻量锁与重量锁的性能对比
 *   TODO
 *      轻量锁用时: 22.764079568s
 *      偏向锁用时: 2.022979843s
 *      重量锁用时: 47.931191223s
 *      实测结果在1亿次加锁自增操作中，偏向锁的效率大概是轻量锁的10倍左右,轻量锁的效率是重量锁的两倍左右
 * @author GPJ
 * @date 2020/6/15 8:38
 * @version 1.0
 **/
@Slf4j
public class JolDemo6 {

    private static long sum = 0;
    private static CountDownLatch countDownLatch;

    public static void main(String[] args) throws InterruptedException {
        int num = 1000000000;
        // 创建一个轻量锁
        Example liteExample = new Example();

        long start = System.nanoTime();
        for (long i = 0; i < num; i++) {
            synchronized (liteExample){
                sum++;
            }
        }
        log.info("{}锁用时: {}s", "轻量", (System.nanoTime() - start)/1000000000.0);


        Thread.sleep(5 * 1000);

        // 创建一个偏向锁
        Example biasedExample = new Example();

        start = System.nanoTime();
        for (long i = 0; i < num; i++) {
            synchronized (biasedExample){
                sum++;
            }
        }
        log.info("{}锁用时: {}s", "偏向", (System.nanoTime() - start)/1000000000.0);


        countDownLatch = new CountDownLatch(num);
        Example weightExample = new Example();

        start = System.nanoTime();
        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                while (countDownLatch.getCount() > 0){
                    synchronized (weightExample){
                        /*if(countDownLatch.getCount() == num/2){
                            log.info(ClassLayout.parseInstance(weightExample).toPrintable());
                        }*/
                        countDownLatch.countDown();;
                    }
                }
            }).start();
        }
        countDownLatch.await();
        log.info("{}锁用时: {}s", "重量", (System.nanoTime() - start)/1000000000.0);
    }
}
